"""
用户模型定义
继承自基础模型，添加用户特有的字段和方法
"""
from typing import Optional

from tortoise import fields
from passlib.context import CryptContext

# 导入基础模型
from pkg.common.models.base_model import BaseModel
from pkg.common.constants.auth import UserStatusInt

# 密码加密上下文
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")


class User(BaseModel):
    """用户模型"""
    
    # 基本信息字段
    username = fields.CharField(max_length=50, unique=True, description="用户名")
    email = fields.CharField(max_length=100, unique=True, null=True, description="邮箱")
    phone = fields.CharField(max_length=20, null=True, description="手机号")
    full_name = fields.CharField(max_length=100, null=True, description="全名")
    avatar = fields.CharField(max_length=500, null=True, description="头像URL")
    
    # 认证相关字段
    password = fields.CharField(max_length=128, description="密码")
    # status = fields.CharField(max_length=20, default=UserStatus.ACTIVE, description="用户状态")
    status = fields.IntField(default=UserStatusInt.ACTIVE, description="用户状态")
    is_superuser = fields.BooleanField(default=False, description="是否超级用户")
    is_verified = fields.BooleanField(default=False, description="是否已验证邮箱")
    
    # 活动信息字段
    last_login = fields.DatetimeField(null=True, description="最后登录时间")
    last_password_change = fields.DatetimeField(null=True, description="最后修改密码时间")
    login_attempts = fields.IntField(default=0, description="登录尝试次数")
    locked_until = fields.DatetimeField(null=True, description="锁定结束时间")
    
    # RBAC权限关系
    # ManyToMany关系将在relations.py中通过关系表定义
    
    class Meta:
        table = "users"
        table_description = "用户表"
        app = "models"
    
    def __str__(self):
        return f"User(id={self.id}, username={self.username})"
    
    def set_password(self, password: str) -> None:
        """设置密码（加密存储）"""
        self.password = pwd_context.hash(password)
    
    def verify_password(self, password: str) -> bool:
        """验证密码"""
        return pwd_context.verify(password, self.password)
    
    def to_dict(self) -> dict:
        """转换为字典，排除敏感信息"""
        base_dict = super().to_dict()  # 获取基础模型的字段
        
        # 移除敏感信息
        if "password" in base_dict:
            del base_dict["password"]
            
        return base_dict
    
    @classmethod
    async def get_by_username(cls, username: str):
        """根据用户名查询用户"""
        return await cls.filter(username=username, is_deleted=False).first()
    
    @classmethod
    async def get_by_email(cls, email: str):
        """根据邮箱查询用户"""
        return await cls.filter(email=email, is_deleted=False).first()
    
    async def has_permission(self, permission_slug: str) -> bool:
        """检查用户是否拥有指定权限
        
        权限检查顺序:
        1. 如果是超级用户，直接返回true
        2. 检查用户直接权限
        3. 检查用户角色的权限
        
        :param permission_slug: 权限标识
        :return: 是否有权限
        """
        # 超级用户拥有所有权限
        if self.is_superuser:
            return True
            
        # 检查直接权限
        from apps.auth.models.permission import Permission
        
        # 通过关联表查询直接权限
        direct_perm_exists = await Permission.filter(
            permission_users__user_id=self.id,
            slug=permission_slug,
            is_deleted=False
        ).exists()
        
        if direct_perm_exists:
            return True
            
        # 检查角色权限
        role_perm_exists = await Permission.filter(
            permission_roles__role__role_users__user_id=self.id,
            slug=permission_slug,
            is_deleted=False
        ).exists()
        
        return role_perm_exists
    
    async def has_role(self, role_slug: str) -> bool:
        """检查用户是否拥有指定角色
        
        :param role_slug: 角色标识
        :return: 是否拥有角色
        """
        # 超级用户拥有所有角色
        if self.is_superuser:
            return True
        
        from apps.auth.models.role import Role
        
        # 通过关联表查询用户角色
        return await Role.filter(
            role_users__user_id=self.id,
            slug=role_slug,
            is_deleted=False
        ).exists()
        
    async def get_permissions(self):
        """获取用户所有权限列表
        
        包括直接权限和通过角色获取的权限
        
        :return: 权限列表
        """
        from apps.auth.models.permission import Permission
        
        # 获取直接权限
        direct_permissions = await Permission.filter(
            permission_users__user_id=self.id,
            is_deleted=False
        ).all()
        
        # 获取角色权限
        role_permissions = await Permission.filter(
            permission_roles__role__role_users__user_id=self.id,
            is_deleted=False
        ).all()
        
        # 合并并去重
        direct_perm_ids = [p.id for p in direct_permissions]
        all_permissions = list(direct_permissions)
        all_permissions.extend([p for p in role_permissions if p.id not in direct_perm_ids])
        
        return all_permissions